class BlackDeathPlayerController extends GamePlayerController
	dependson(BlackDeathPawn);

var BD_UseableObject SightedUseableObject;
var name lastStateBeforeAttack;

var float forcedStepSpeed;
var float forceForward;

var bool bUsingBlackDeathMovemnt; //Used to identify the first tick after BlackDeathHeroPawn.bWeaponFiring becomes false

simulated event PostBeginPlay()
{
	super.PostBeginPlay();
	UpdateUseable();
	setTimer(0.2, true, 'UpdateUseable');//continuoucsly check for new useables
}

/**PlayerMove and UpdateRotation are overritten here to capture control of player's movement during attack sequences, and
 * implement alternative movement controls in these scenerios**/
state PlayerWalking
{
	function PlayerMove( float DeltaTime )
	{
		local vector			X,Y,Z, NewAccel;
		local eDoubleClickDir	DoubleClickMove;
		//local rotator			OldRotation;
		//local Rotator           ViewRotation, NewRotation, Deltarot;

		if(BlackDeathHeroPawn(Pawn).bWeaponFiring)
		{
			bUsingBlackDeathMovemnt = true;

			GetAxes(Pawn.Rotation,X,Y,Z);

			// Update acceleration.
			NewAccel = forceForward*X;
			NewAccel.Z	= 0;
			NewAccel = forcedStepSpeed * Normal(NewAccel);

			DoubleClickMove = PlayerInput.CheckForDoubleClickMove( DeltaTime/WorldInfo.TimeDilation );

			// Update rotation.
			//OldRotation = Rotation;
			//UpdateRotation( DeltaTime );
			
			//make sure there is constant ground speed for this
			BlackDeathHeroPawn(Pawn).SetBaseSpeed(BlackDeathHeroPawn(Pawn).DefaultRunSpeed);
			BlackDeathHeroPawn(Pawn).ResetSpeed(); 
			ProcessMove(DeltaTime, NewAccel, DoubleClickMove, Rotation);

		}
		else
		{
			/*if(bUsingBlackDeathMovemnt)
			{
				//Here we know that the player has just stopped "firing" his melee weapon, and rotation has just been unlocked
				bUsingBlackDeathMovemnt = false;
				
				DeltaRot.Yaw	= PlayerInput.aTurn;
				DeltaRot.Pitch	= PlayerInput.aLookUp;

				ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot );
				//ViewShake( deltaTime );
				NewRotation = ViewRotation;
				NewRotation.Roll = Rotation.Roll;
				Pawn.SetDesiredRotation(NewRotation, true, true, 2.0);
			}*/
			super.PlayerMove(DeltaTime);
		}
	}
}
/*
function UpdateRotation( float DeltaTime )
{
	local Rotator	DeltaRot, newRotation, ViewRotation;
	
	if(BlackDeathHeroPawn(Pawn).bWeaponFiring)
	{
		ViewRotation = Rotation;
		if (Pawn!=none)
		{
			SetDesiredRotation(ViewRotation);
		}

		// Calculate Delta to be applied on ViewRotation
		DeltaRot.Yaw	= PlayerInput.aTurn;
		DeltaRot.Pitch	= PlayerInput.aLookUp;

		ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot );
		SetRotation(ViewRotation);

		ViewShake( deltaTime );

		NewRotation = ViewRotation;
		NewRotation.Roll = Rotation.Roll;

		if ( Pawn != None )
			Pawn.FaceRotation(NewRotation, deltatime);
	}
}
*/
function StartForwardMovement(float speed)
{
	forceForward = 1;
	forcedStepSpeed = speed;
}

function StopForwardMovement()
{
	forceForward = 0;
	forcedStepSpeed = default.forcedStepSpeed;
	BlackDeathHeroPawn(Pawn).ResetSpeed();
	if(BlackDeathHeroPawn(Pawn).bUsingStamina)
		BlackDeathHeroPawn(Pawn).ApplySpeedMultiplier(3.0);
	else
		BlackDeathHeroPawn(Pawn).CheckHealthState();
}

exec function HolyHandGrenade()//Some men just want to see the world burn
{
	local BlackDeathPawn BDP;
	foreach AllActors(class'BlackDeathPawn', BDP)
	{
		BDP.Ignite();
	}
}

exec function FinishHim()
{
	BlackDeathHeroPawn(Pawn).Finisher();
}

exec function LightMe()//If you insist
{
	BlackDeathPawn(Pawn).ignite();
}

exec function MassBurial()
{
	local BlackDeathZombiePawn BDZP;
	foreach AllActors(class'BlackDeathZombiePawn', BDZP)
	{
		BDZP.takedamage(100, None, Location, vect(0,0,0), class'DmgType_Crushed');
	}
}

function UpdateUseable()
{
	if(BlackDeathHeroPawn(Pawn) != none)
	{
		SightedUseableObject = getSightedUseable();
		//WorldInfo.Game.Broadcast(None, SightedUseableObject);//`log("SightedUseable is: "@SightedUseableObject);
	}
}

function bool PerformedUseAction()
{
	if( WorldInfo.Pauser == PlayerReplicationInfo )
	{
		if( Role == Role_Authority )
		{
			// unpause and move on
			SetPause( false );
		}
		return true;
	}

    	if ( Pawn == None )
	{
		return true;
	}

	if( Role < Role_Authority )
	{
		return false;
	}

	if( Vehicle(Pawn) != None )
	{
		return Vehicle(Pawn).DriverLeave(false);
	}

	if(SightedUseableObject != none)
	{
		return SightedUseableObject.use(pawn);
	}
	
	if(BlackDeathHeroPawn(Pawn).Finisher())
	{
		return true;
	}

	return TriggerInteracted();
}

//Check for and return the "best" (one we're are most faceing) useable object from the pawn
function BD_UseableObject getSightedUseable()
{
	local BD_UseableObject O, Best;
	local vector ViewDir, PawnLoc2D, OLoc2D;
	local float NewDot, BestDot;

	PawnLoc2D = Pawn.Location;
	PawnLoc2D.Z = 0;
	ViewDir = vector(Pawn.Rotation);

	ForEach Pawn.OverlappingActors(class'BD_UseableObject', O, BlackDeathHeroPawn(Pawn).UseableCheckRadius)
	{
		if(O.benabled)//check aginst only enabled objects
		{
			OLoc2D = O.Location;
			Oloc2D.Z = 0;
			NewDot = Normal(OLoc2D-PawnLoc2D) Dot ViewDir;
			if ( ((Best == None) || (NewDot > BestDot)) && Newdot >= 0.5 )
			{
				// check that object is visible
				if ( FastTrace(O.Location,Pawn.Location) )
				{
					Best = O;
					BestDot = NewDot;
				}
			}
		}
	}
	return Best;
}
	
exec function Run()
{
	if(BlackDeathHeroPawn(Pawn) != none)
	{
		BlackDeathHeroPawn(Pawn).StartRun();
	}
}

exec function EndRun()
{
	if(BlackDeathHeroPawn(Pawn) != none)
	{
		BlackDeathHeroPawn(Pawn).EndRun();
	}
}	

exec function ToggleAttacking()
{
	if(BlackDeathHeroPawn(Pawn) != none)
	{
		BlackDeathHeroPawn(Pawn).ToggleAttacking();
	}
}

exec function ToggleCam()
{
	if(BlackDeathCamera(PlayerCamera).CameraStyle == 'ThirdPerson')
	{
		BlackDeathCamera(PlayerCamera).ToggleShoulder();
	}
}


exec function ToggleJog()
{
	if(BlackDeathHeroPawn(Pawn) != none)
		{
			BlackDeathHeroPawn(Pawn).StartJog();
		}
}


exec function ToggleRun()
{
	if(BlackDeathHeroPawn(Pawn) != none)
	{
		BlackDeathHeroPawn(Pawn).ToggleRun();
	}
}
exec function ToggleWalk()
{
	if(BlackDeathHeroPawn(Pawn) != none)
	{
		BlackDeathHeroPawn(Pawn).ToggleWalk();
	}
}

exec function ToggleLook()
{
	BlackDeathHeroPawn(Pawn).goToFirstPersonMode();
}


exec function PrevWeapon()
{
	if ( WorldInfo.Pauser!=None )
		return;
	if(Pawn.isInState('Attacking'))
		Pawn.InvManager.PrevWeapon();
	else
		ToggleAttacking();
}

exec function NextWeapon()
{
	if ( WorldInfo.Pauser!=None )
		return;
	if(Pawn.isInState('Attacking'))
		Pawn.InvManager.NextWeapon();
	else
		ToggleAttacking();
}

defaultproperties
{
	forceForward = 0
	forcedStepSpeed = 200
	DesiredFOV=90.000000
	CameraClass=class'BlackDeath.BlackDeathCamera'
	InputClass=class'BlackDeath.BlackDeathInput'
}


